home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / RTrace 1.0 / source / alias.c next >
Encoding:
C/C++ Source or Header  |  1992-08-16  |  13.5 KB  |  443 lines  |  [TEXT/KAHL]

  1. /*
  2.  * Copyright (c) 1988, 1992 Antonio Costa, INESC-Norte.
  3.  * All rights reserved.
  4.  *
  5.  * This code received contributions from the following people:
  6.  *
  7.  *  Roman Kuchkuda      - basic ray tracer
  8.  *  Mark VandeWettering - MTV ray tracer
  9.  *  Augusto Sousa       - overall, shading model
  10.  *
  11.  * Redistribution and use in source and binary forms are permitted
  12.  * provided that the above copyright notice and this paragraph are
  13.  * duplicated in all such forms and that any documentation,
  14.  * advertising materials, and other materials related to such
  15.  * distribution and use acknowledge that the software was developed
  16.  * by Antonio Costa, at INESC-Norte. The name of the author and
  17.  * INESC-Norte may not be used to endorse or promote products derived
  18.  * from this software without specific prior written permission.
  19.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  20.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  21.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  22.  */
  23. #include "defs.h"
  24. #include "extern.h"
  25.  
  26. /**********************************************************************
  27.  *    RAY TRACING - Antialiasing - Version 7.3                        *
  28.  *                                                                    *
  29.  *    MADE BY    : Antonio Costa, INESC-Norte, October 1988           *
  30.  *    ADAPTED BY : Antonio Costa, INESC-Norte, June 1989              *
  31.  *    MODIFIED BY: Antonio Costa, INESC-Norte, June 1992              *
  32.  **********************************************************************/
  33.  
  34. /***** Adaptive supersampling Antialiasing *****/
  35. #define SAMPLING_DIVISIONS_MAX ((1 SHL SAMPLING_LEVEL_MAX) - 1)
  36. static pixel_struct pixel[SAMPLING_DIVISIONS_MAX][SAMPLING_DIVISIONS_MAX];
  37.  
  38. static boolean
  39. big_color_change(weight, pixel0, pixel1, pixel2, pixel3, ids, id)
  40.   int             weight;
  41.   pixel_ptr       pixel0, pixel1, pixel2, pixel3;
  42.   int            *ids;
  43.   list_id         id;
  44. {
  45.   boolean         color_change;
  46.   REG int         i, j;
  47.   REG real        r, g, b;
  48.   rgb_struct      color[4];
  49.  
  50.   if (weight < sampling_weight)
  51.   {
  52.     STRUCT_ASSIGN(color[0], pixel0->color);
  53.     STRUCT_ASSIGN(color[1], pixel1->color);
  54.     STRUCT_ASSIGN(color[2], pixel2->color);
  55.     STRUCT_ASSIGN(color[3], pixel3->color);
  56.     i = -1;
  57.     do
  58.     {
  59.       POSINC(i);
  60.       j = i;
  61.       do
  62.       {
  63.         POSINC(j);
  64.         r = color[i].r - color[j].r;
  65.         g = color[i].g - color[j].g;
  66.         b = color[i].b - color[j].b;
  67.         color_change = (boolean) (SQR(r) + SQR(g) + SQR(b) >
  68.                                   threshold_color);
  69.       }
  70.       while ((j != 3) AND NOT color_change);
  71.     }
  72.     while ((i != 2) AND NOT color_change);
  73.     if (color_change)
  74.     {
  75.       *ids = 1;
  76.       id[0] = pixel0->id;
  77.       if (pixel1->id != pixel0->id)
  78.         id[POSINC(*ids)] = pixel1->id;
  79.       if ((pixel2->id != pixel1->id) AND(pixel2->id != pixel0->id))
  80.         id[POSINC(*ids)] = pixel2->id;
  81.       if ((pixel3->id != pixel2->id) AND(pixel3->id != pixel1->id)
  82.           AND(pixel3->id != pixel0->id))
  83.         id[POSINC(*ids)] = pixel3->id;
  84.       return TRUE;
  85.     }
  86.     return FALSE;
  87.   } else
  88.     return FALSE;
  89. }
  90. static void
  91. intersect_list(ray, ids, id, pixel)
  92.   ray_ptr         ray;
  93.   int             ids;
  94.   list_id         id;
  95.   pixel_ptr       pixel;
  96. {
  97.   REG int         i;
  98.   REG real        small_distance, max_distance;
  99.   real            distance;
  100.   xyz_struct      hit, normal;
  101.   object_ptr      intersect_object;
  102.  
  103.   REALINC(eye_rays);
  104.   max_distance = INFINITY;
  105.   pixel->id = NO_OBJECTS;
  106.   PQUEUE_INITIALIZE;
  107.   for (i = 0; i < ids; POSINC(i))
  108.   {
  109.     if (id[i] == NO_OBJECTS)
  110.       continue;
  111.     if (CHECK_BOUNDS(object[id[i]]->object_type))
  112.     {
  113.       distance = bound_intersect(&eye, &(ray->vector), object[id[i]]->min,
  114.                                  object[id[i]]->max);
  115.       if ((distance <= 0.0) OR(distance >= max_distance))
  116.         continue;
  117.       pqueue_insert(distance, object[id[i]]);
  118.     } else
  119.     {
  120.       OBJECT_INTERSECT(distance, &eye, &(ray->vector), object[id[i]]);
  121.       if ((distance <= 0.0) OR(distance >= max_distance))
  122.         continue;
  123.       max_distance = distance;
  124.       pixel->id = object[id[i]]->id;
  125.     }
  126.   }
  127.   small_distance = max_distance;
  128.   while (PQUEUE_NOT_EMPTY)
  129.   {
  130.     pqueue_extract(&distance, &intersect_object);
  131.     if (distance > small_distance)
  132.       break;
  133.     if (CHECK_BOUNDS(intersect_object->object_type))
  134.       OBJECT_INTERSECT(distance, &eye, &(ray->vector), intersect_object);
  135.     if ((distance > 0.0) AND(distance < small_distance))
  136.     {
  137.       REALINC(ray_hits);
  138.       pixel->id = intersect_object->id;
  139.       small_distance = distance;
  140.     }
  141.   }
  142.   if ((intersect_mode == 1) AND(pixel->id == NO_OBJECTS))
  143.   {
  144.     REALINC(eye_rays);
  145.     if (intersect_all(NO_OBJECTS, &eye, ray, &(pixel->color)) > 0.0)
  146.     {
  147.       pixel->id = ray_cache[0];
  148.       return;
  149.     }
  150.   }
  151.   if (pixel->id == NO_OBJECTS)
  152.   {
  153.     STRUCT_ASSIGN(pixel->color, back_color);
  154.     return;
  155.   }
  156.   hit.x = eye.x + small_distance * ray->vector.x;
  157.   hit.y = eye.y + small_distance * ray->vector.y;
  158.   hit.z = eye.z + small_distance * ray->vector.z;
  159.   intersect_object = object[pixel->id];
  160.   OBJECT_NORMAL(&hit, intersect_object, &normal);
  161.   shade(&hit, &normal, ray, intersect_object, &(pixel->color));
  162.   ATTEN_COLOR(small_distance, TRUE, TRUE, TRUE, pixel->color, pixel->color);
  163. }
  164. #define GET_POINT(dx, dy, i, j)\
  165. do {\
  166.   (i) = ROUND((real) sampling_divisions * (dx));\
  167.   (j) = ROUND((real) sampling_divisions * (dy));\
  168.   if (((i) == 0) OR((i) == sampling_divisions)\
  169.       OR((j) == 0) OR((j) == sampling_divisions))\
  170.     (i) = -1;\
  171.   else\
  172.   {\
  173.     POSDEC(i);\
  174.     POSDEC(j);\
  175.   }\
  176. } while (0)
  177. #define AVERAGE_PIXEL(weight)\
  178. do {\
  179.   REG real        w;\
  180. \
  181.   w = 1.0 / (real) (weight);\
  182.   color->r += (pixel0->color.r + pixel2->color.r + pixel6->color.r +\
  183.                pixel8->color.r) * w;\
  184.   color->g += (pixel0->color.g + pixel2->color.g + pixel6->color.g +\
  185.                pixel8->color.g) * w;\
  186.   color->b += (pixel0->color.b + pixel2->color.b + pixel6->color.b +\
  187.                pixel8->color.b) * w;\
  188.   if (background_mode == 1)\
  189.   {\
  190.     if (pixel0->id == NO_OBJECTS)\
  191.       pixel_mask += w;\
  192.     if (pixel2->id == NO_OBJECTS)\
  193.       pixel_mask += w;\
  194.     if (pixel6->id == NO_OBJECTS)\
  195.       pixel_mask += w;\
  196.     if (pixel8->id == NO_OBJECTS)\
  197.       pixel_mask += w;\
  198.   }\
  199. } while (0)
  200.  
  201. static real       pixel_mask;
  202. static void
  203. find_color_adaptive(xr, yr, x, y, delta, pixel0, pixel2, pixel6, pixel8,
  204.                     weight, color)
  205.   REG real        xr, yr, x, y, delta;
  206.   pixel_ptr       pixel0, pixel2, pixel6, pixel8;
  207.   int             weight;
  208.   rgb_ptr         color;
  209. {
  210.   int             i, j, ids;
  211.   REG real        x0, y0, delta0;
  212.   list_id         id;
  213.   pixel_struct    pixel1, pixel3, pixel4, pixel5, pixel7;
  214.   ray_struct      ray0;
  215.  
  216.   if (big_color_change(weight, pixel0, pixel2, pixel6, pixel8, &ids, id))
  217.   {
  218.     REALINC(pixel_divisions);
  219.     delta0 = delta * 0.5;
  220.     x0 = x - delta0;
  221.     y0 = y - delta0;
  222.     ray0.level.r = 1.0;
  223.     ray0.level.g = 1.0;
  224.     ray0.level.b = 1.0;
  225.     ray0.inside = FALSE;
  226.     /* 1st quadrant */
  227.     /* Point 1 */
  228.     GET_POINT(xr - x0, yr - (y - delta), i, j);
  229.     if (i < 0)                  /* Edges */
  230.     {
  231.       make_vector(&(ray0.vector), x0, y - delta, delta0);
  232.       intersect_list(&ray0, ids, id, &pixel1);
  233.     } else
  234.     {
  235.       if (pixel[i][j].id >= NO_OBJECTS) /* Done */
  236.         STRUCT_ASSIGN(pixel1, pixel[i][j]);
  237.       else                      /* Not done */
  238.       {
  239.         make_vector(&(ray0.vector), x0, y - delta, delta0);
  240.         intersect_list(&ray0, ids, id, &pixel1);
  241.         STRUCT_ASSIGN(pixel[i][j], pixel1);
  242.       }
  243.     }
  244.     /* Point 3 */
  245.     GET_POINT(xr - (x - delta), yr - y0, i, j);
  246.     if (i < 0)                  /* Edges */
  247.     {
  248.       make_vector(&(ray0.vector), x - delta, y0, delta0);
  249.       intersect_list(&ray0, ids, id, &pixel3);
  250.     } else
  251.     {
  252.       if (pixel[i][j].id >= NO_OBJECTS) /* Done */
  253.         STRUCT_ASSIGN(pixel3, pixel[i][j]);
  254.       else                      /* Not done */
  255.       {
  256.         make_vector(&(ray0.vector), x - delta, y0, delta0);
  257.         intersect_list(&ray0, ids, id, &pixel3);
  258.         STRUCT_ASSIGN(pixel[i][j], pixel3);
  259.       }
  260.     }
  261.     /* Point 4 */
  262.     GET_POINT(xr - x0, yr - y0, i, j);
  263.     if (i < 0)                  /* Edges */
  264.     {
  265.       make_vector(&(ray0.vector), x0, y0, delta0);
  266.       intersect_list(&ray0, ids, id, &pixel4);
  267.     } else
  268.     {
  269.       if (pixel[i][j].id >= NO_OBJECTS) /* Done */
  270.         STRUCT_ASSIGN(pixel4, pixel[i][j]);
  271.       else                      /* Not done */
  272.       {
  273.         make_vector(&(ray0.vector), x0, y0, delta0);
  274.         intersect_list(&ray0, ids, id, &pixel4);
  275.         STRUCT_ASSIGN(pixel[i][j], pixel4);
  276.       }
  277.     }
  278.     find_color_adaptive(xr, yr, x0, y0, delta0,
  279.                         pixel0, &pixel1, &pixel3, &pixel4,
  280.                         weight * 4, color);
  281.     /* 2nd quadrant */
  282.     /* Point 5 */
  283.     GET_POINT(xr - x, yr - y0, i, j);
  284.     if (i < 0)                  /* Edges */
  285.     {
  286.       make_vector(&(ray0.vector), x, y0, delta0);
  287.       intersect_list(&ray0, ids, id, &pixel5);
  288.     } else
  289.     {
  290.       if (pixel[i][j].id >= NO_OBJECTS) /* Done */
  291.         STRUCT_ASSIGN(pixel5, pixel[i][j]);
  292.       else                      /* Not done */
  293.       {
  294.         make_vector(&(ray0.vector), x, y0, delta0);
  295.         intersect_list(&ray0, ids, id, &pixel5);
  296.         STRUCT_ASSIGN(pixel[i][j], pixel5);
  297.       }
  298.     }
  299.     find_color_adaptive(xr, yr, x, y0, delta0,
  300.                         &pixel1, pixel2, &pixel4, &pixel5,
  301.                         weight * 4, color);
  302.     /* 3rd quadrant */
  303.     /* Point 7 */
  304.     GET_POINT(xr - x0, yr - y, i, j);
  305.     if (i < 0)                  /* Edges */
  306.     {
  307.       make_vector(&(ray0.vector), x0, y, delta0);
  308.       intersect_list(&ray0, ids, id, &pixel7);
  309.     } else
  310.     {
  311.       if (pixel[i][j].id >= NO_OBJECTS) /* Done */
  312.         STRUCT_ASSIGN(pixel7, pixel[i][j]);
  313.       else                      /* Not done */
  314.       {
  315.         make_vector(&(ray0.vector), x0, y, delta0);
  316.         intersect_list(&ray0, ids, id, &pixel7);
  317.         STRUCT_ASSIGN(pixel[i][j], pixel7);
  318.       }
  319.     }
  320.     find_color_adaptive(xr, yr, x0, y, delta0,
  321.                         &pixel3, &pixel4, pixel6, &pixel7,
  322.                         weight * 4, color);
  323.     /* 4th quadrant */
  324.     find_color_adaptive(xr, yr, x, y, delta0,
  325.                         &pixel4, &pixel5, &pixel7, pixel8,
  326.                         weight * 4, color);
  327.   } else
  328.     AVERAGE_PIXEL(weight);
  329. }
  330. static void
  331. find_color_fixed(x, y, ids, id, pixel0, pixel2, pixel6, pixel8, color)
  332.   real            x, y;
  333.   int             ids;
  334.   list_id         id;
  335.   pixel_ptr       pixel0, pixel2, pixel6, pixel8;
  336.   rgb_ptr         color;
  337. {
  338.   REG int         weight, i, j;
  339.   REG real        delta, delta0, w;
  340.   pixel_struct    pixel_temp;
  341.   ray_struct      ray0;
  342.  
  343.   weight = SQR(sampling_divisions) + 4;
  344.   w = 1.0 / (real) weight;
  345.   AVERAGE_PIXEL(weight);
  346.   ray0.level.r = 1.0;
  347.   ray0.level.g = 1.0;
  348.   ray0.level.b = 1.0;
  349.   ray0.inside = FALSE;
  350.   delta = 1.0 / (real) sampling_divisions;
  351.   delta0 = delta * 0.5;
  352.   x -= delta0;
  353.   y -= delta0;
  354.   for (i = 0; i < sampling_divisions; POSINC(i))
  355.     for (j = 0; j < sampling_divisions; POSINC(j))
  356.     {
  357.       REALINC(pixel_divisions);
  358.       make_vector(&(ray0.vector), x - (real) i * delta,
  359.                   y - (real) j * delta, delta0);
  360.       if (antialiasing_mode == 1)
  361.       {
  362.         intersect_list(&ray0, ids, id, &pixel_temp);
  363.         color->r += pixel_temp.color.r * w;
  364.         color->g += pixel_temp.color.g * w;
  365.         color->b += pixel_temp.color.b * w;
  366.         if (background_mode == 1)
  367.           if (pixel_temp.id == NO_OBJECTS)
  368.             pixel_mask += w;
  369.       } else
  370.       {
  371.         REALINC(eye_rays);
  372.         if (intersect_all(NO_OBJECTS, &eye, &ray0, &(pixel_temp.color)) >
  373.             0.0)
  374.         {
  375.           color->r += pixel_temp.color.r * w;
  376.           color->g += pixel_temp.color.g * w;
  377.           color->b += pixel_temp.color.b * w;
  378.         } else
  379.         {
  380.           color->r += back_color.r * w;
  381.           color->g += back_color.g * w;
  382.           color->b += back_color.b * w;
  383.           if (background_mode == 1)
  384.             pixel_mask += w;
  385.         }
  386.       }
  387.     }
  388. }
  389. static void
  390. find_color(x, y, pixel0, pixel2, pixel6, pixel8, color)
  391.   int             x, y;
  392.   pixel_ptr       pixel0, pixel2, pixel6, pixel8;
  393.   rgb_ptr         color;
  394. {
  395.   int             ids;
  396.   list_id         id;
  397.  
  398.   if (sampling_levels == 0)
  399.   {
  400.     AVERAGE_PIXEL(4);
  401.     return;
  402.   }
  403.   switch (antialiasing_mode)
  404.   {
  405.     case 0:
  406.       find_color_adaptive((real) x, (real) y, (real) x, (real) y, 1.0,
  407.                           pixel0, pixel2, pixel6, pixel8, 4, color);
  408.       return;
  409.     case 1:
  410.       if (big_color_change(4, pixel0, pixel2, pixel6, pixel8, &ids, id))
  411.         find_color_fixed((real) x, (real) y, ids, id,
  412.                          pixel0, pixel2, pixel6, pixel8, color);
  413.       else
  414.         AVERAGE_PIXEL(4);
  415.       return;
  416.     case 2:
  417.       find_color_fixed((real) x, (real) y, 0, id,
  418.                        pixel0, pixel2, pixel6, pixel8, color);
  419.       return;
  420.   }
  421. }
  422. void
  423. find_true_color(x, y, pixel0, pixel2, pixel6, pixel8, true_color)
  424.   int             x, y;
  425.   pixel_ptr       pixel0, pixel2, pixel6, pixel8;
  426.   rgb_ptr         true_color;
  427. {
  428.   REG int         i, j;
  429.  
  430.   if (antialiasing_mode == 0)
  431.     for (i = 0; i < PRED(sampling_divisions); POSINC(i))
  432.       for (j = 0; j < PRED(sampling_divisions); POSINC(j))
  433.         pixel[i][j].id = -1;
  434.   true_color->r = 0.0;
  435.   true_color->g = 0.0;
  436.   true_color->b = 0.0;
  437.   if (background_mode == 1)
  438.     pixel_mask = 0.0;
  439.   find_color(x, y, pixel0, pixel2, pixel6, pixel8, true_color);
  440.   if (background_mode == 1)
  441.     back_mask[x] = pixel_mask;
  442. }
  443.